<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2018/6/7
 * Time: 1:51
 */

namespace app\api\controller\v2;

use app\aliyun\controller\AliyunFilterWord;
use app\common\cachemodel\FortuneCache;
use app\common\cachemodel\Recode;
use app\common\cachemodel\Wechat;
use app\common\cachemodel\ZlUserVip;
use app\common\lib\exception\ApiException;
use app\common\lib\PushQueue;
use app\common\model\RecodeCat;
use app\common\model\Rectification as RectificationModel;
use app\common\model\User;
use Exception;
use think\Cache;
use think\Db;
use think\Log;
use think\response\Json;

/**个人信息修改接口
 * @title
 * @desc
 * @url
 * @version 2.0.0
 * Class Demo
 * @package app\api\controller\v2
 */
class Info extends Auth
{
    protected $restActionList = ['index', 'read', 'save', 'update', 'delete'];
    protected $noNeedJudgeSummer = ['香港特别行政区', '澳门特别行政区', '台湾省', '北美洲', '大洋洲', '非洲', '南美洲', '欧洲', '亚洲', ''];

    /**
     * 获取个人中心数据
     * @return Json
     */
    public function index()
    {
        try
        {
            $data = [];
            $recode = (new Recode())->getRecodeLists($this->user['id'], 1);
            $data['name'] = $recode['name'];
            $data['sex'] = (int)$recode['type'] === 1 ? 1 : 2;
            $data['year'] = (int)$recode['year'];
            $data['month'] = (int)sprintf('%02u', $recode['month']);
            $data['day'] = (int)sprintf('%02u', $recode['day']);
            $data['hour'] = (int)sprintf('%02u', $recode['hour']);
            $data['minute'] = (int)sprintf('%02u', $recode['minute']);
            $data['timezone'] = (int)$recode['timezone'];
            $data['birth_country'] = $recode['birth_country'];
            $data['birth_province'] = $recode['birth_province'];
            $data['birth_city'] = $recode['birth_city'];
            $data['long_deg'] = (int)$recode['long_deg'];
            $data['long_min'] = (int)$recode['long_min'];
            $data['ew'] = (int)$recode['ew'];
            $data['lat_deg'] = (int)$recode['lat_deg'];
            $data['lat_min'] = (int)$recode['lat_min'];
            $data['ns'] = (int)$recode['ns'];
            $data['avatar'] = $recode['avatar'];

            //判断用户是否绑定微信
            $wechat_info = (new Wechat())->getWechatInfo($this->user['id'], 2);
            if ($wechat_info)
            {
                $data['nickname'] = $wechat_info['nickname'];
            } else
            {
                $data['nickname'] = '';
            }
            $field = 'id,status';
            //判断用户是否矫正中
            $where = ['uid' => $this->user['id'], 'status' => ['eq', 1]];
            $rectification = (new RectificationModel())
                ->field($field)
                ->where($where)
                ->count('id');

            if ($rectification > 0)
            {
                $data['is_rectification'] = 1;
            } else
            {
                $data['is_rectification'] = 0;
            }

        }
        catch (Exception $e)
        {
            return show(config('code.denied'), '用户信息获取失败,请重新登录');
        }

        if ($this->user['tel'])
        {
            $data['tel'] = substr_replace($this->user['tel'], '****', 3, 4);
        }

        return show(200, '成功', $data);
    }

    /**
     * 个人中心绑定手机号
     * @return Json
     */
    public function bind_tel()
    {
        $tel = input('post.tel/s');
        $code = input('post.code/d');
        if (!$tel || !$code || strlen($code) != 6)
        {
            return show(config('code.error'), '验证码错误');
        }

        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            return show(config('code.error'), '手机号无效');
        }
        $time = time();// 当前时间  有效时间暂定为十分钟 600s
        // 判断给手机是否已经注册过
        try
        {
            $user = Db::table('app_user')
                ->field('id,tel,nickname,avatar,forbidden,email,is_first_login,uc_id,has_self_recode')
                ->where('tel', (string)$tel)
                ->find();
        }
        catch (Exception $e)
        {
            Log::write('绑定手机接口，获取用户注册信息失败：' . $e->getMessage(), 'error', true);
        }
        if (empty($user) || $user === null)
        {
            // 若未注册
            try
            {
                $appConfig = config('app');
                //内部用户过滤验证码验证
                if (!in_array($tel, $appConfig['mobile'])
                    || $code != substr($appConfig['code'] * (substr($tel, 3, 6)), 0, 6))
                {
                    //苹果和安卓应用商店审核账号，固定验证码为666666
                    if (($tel == '13045794520' && $code == '666666')
                        || ($tel == '13261877781' && $code == '666666'))
                    {

                    } else
                    {
                        // 判断code是否正确
                        $data = Db::table('app_tel_login')->where(['tel' => (string)$tel, 'code' => (string)$code])->find();
                        // code输入错误
                        if (empty($data))
                        {
                            return show(config('code.error'), '验证码错误');
                        }
                        // 判断code是否过期
                        if ($data['expire_time'] < $time)
                        {
                            return show(config('code.error'), '验证码过期');
                        }
                    }
                }
                // 开始绑定手机号
                (new User())->updateUserinfo(['id' => $this->user['id']], ['tel' => $tel]);
                (new ZlUserVip())->updateStarNum((int)$this->user['id'], 13); // 绑定手机号任务
                return show(200, '绑定成功');

            }
            catch (Exception $e)
            {
                Log::write('绑定手机失败请求数据：' . $tel . '【' . $e->getFile() . $e->getLine() . '】', 'error', true);
                return show(config('code.error'), '绑定失败请稍后再试');
            }
        } else
        {
            return show(config('code.error'), '该手机号已被其他账号绑定');
        }
    }

    /**
     * 更换手机
     * @return Json
     */
    public function change_tel()
    {
        $old_tel = input('param.old_tel/s', '');
        $tel = input('param.tel/s', '');
        $code = input('param.code/d', 0);

        if (!$old_tel || !$tel || !$code || strlen($code) != 6)
        {
            return show(config('code.error'), '验证码错误');
        }
        if (!preg_match("/^1[3456789]{1}\d{9}$/", $tel))
        {
            return show(config('code.error'), '手机号无效');
        }
//        判断原手机号是否正确
        if (strcasecmp($old_tel, $this->user['tel']) != 0)
        {
            return show(config('code.error'), '原手机号错误');
        }
        try
        {
            // 判断新手机是否已经注册过
            $user = Db::table('app_user')
                ->field('tel')
                ->where('tel', (string)$tel)
                ->findOrFail();
        }
        catch (Exception $e)
        {
            $user = [];
        }

        // 若未注册
        if (empty($user) || $user === null)
        {
            try
            {
                // 判断code是否正确
                Db::table('app_tel_login')->where(['tel' => (string)$tel, 'code' => (string)$code])->findOrFail();
                (new User())->updateUserinfo(['id' => $this->user['id']], ['tel' => $tel]);
            }
            catch (ApiException $ae)
            {
                return show(config('code.error'), '操作失败，请稍后重试。');
            }
            catch (Exception $e)
            {
                Log::write('更换手机号失败：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error', true);
                return show(config('code.error'), '验证码错误');
            }
            return show(config('code.success'), '操作成功');
        }
        return show(config('code.error'), '该手机号已被其他账号绑定');
    }

    /**
     * 修改档案出生时间
     * @return Json
     * @throws Exception
     */
    public function alter_time()
    {
        $year = input('param.year/d');// 出生时间-年
        $month = input('param.month/d');// 出生时间-月
        $uid = $this->user['id'];
        $day = input('param.day/d');// 出生时间-日
        $hour = input('param.hour/d');// 出生时间-时
        $minute = input('param.minute/d');// 出生时间-分
        $timezone = input('param.timezone/d', 8);// 出生时间-时区

        $RecodeModel = new Recode();
        $RecodeCatModel = new RecodeCat();


        // 获取档案信息
        try
        {
            $recode_old = $RecodeModel->getRecodeLists($this->user['id'], 1);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '获取档案信息失败');
        }

        if (!in_array($recode_old['birth_country'], $this->noNeedJudgeSummer))
        {
            $is_summer = isSummerTime($hour, $minute, 0, $month, $day, $year) ? 1 : 0;// 是否开启夏令时
        } else
        {
            $is_summer = 0;
        }

        $data = [
            'year' => $year,
            'month' => $month,
            'day' => $day,
            'hour' => $hour,
            'minute' => $minute,
            'timezone' => $timezone,
            'is_summer' => $is_summer,
        ];
//       检查档案时间格式
        checkRecodeData($year, $month, $day, $hour, $minute, $timezone);

        //获取档案所属档案袋id
        $recode_cat_id = $RecodeCatModel->getRecodeCatId(['uid' => $uid, 'rid' => $recode_old['id']]);
        // 编辑档案前检测是否 有相关订单
        $rec = $RecodeModel::checkAboutOrders(['uid' => $uid, 'id' => $recode_old['id']]);

        // 若有，则档案时间只能为当天内变动，若跨日期，则只能在两小时以内变动
        if ($rec === true)
        {
            // 判断or_day是否存在
            if (empty($recode_old['or_day']) || !$recode_old['or_day'])
            {
                $recode_old['or_day'] = $recode_old['day'];
                $data['or_day'] = $recode_old['day'];
            }

            $time = strtotime($recode_old['year'] . '-' . $recode_old['month'] . '-' . $recode_old['or_day'] . ' 12:00');
            $max = $time + 3600 * 14;
            $min = $time - 3600 * 14;

            $now_time = $time = strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute);

            if ($now_time > $max || $now_time < $min)
            {
                return show(config('code.error'), '由于该档案购买过付费项目，修改功能受限，改后时间不能与原档案时间差超过两个小时');
            }

        }

        $longitude = ($recode_old['long_deg'] + $recode_old['long_min'] / 60) * $recode_old['ew'];
        $latitude = ($recode_old['lat_deg'] + $recode_old['lat_min'] / 60) * $recode_old['ns'];
        // 查询当前星盘日月水金火木土等星落座落宫存入数据库
        $astro_data = getTheRecodeAstro($year, $month, $day, $hour, $minute, $longitude, $latitude, $timezone);
        try
        {
            // 更新档案
            $RecodeModel->UpdateData($this->user['id'], $recode_old['id'], array_merge($data, $astro_data));
            Db::table('app_recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data);// 更新档案行星数据
        }
        catch (Exception $e)
        {
            Log::write('个人中心修改时间失败：' . $e->getMessage() . '【' . $e->getFile() . $e->getLine() . '】', 'error', true);
            return show(config('code.error'), '修改信息失败，请稍后再试', []);
        }

        // 档案更新时更新用户档案缓存
        Cache::rm('recode_' . $recode_old['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::rm('recode_astro_' . $recode_old['id']);
        //删除首页用户星座缓存
        //Cache::rm('d_f_h_sun_in_sign_' . $recode_old['id']);
        FortuneCache::rmFortuneDayCache($recode_old['id'], strtotime(date('Y-m-d') . ' 12:00:00'));

        $array = [
            'id' => $recode_old['id'],
            'cid' => $recode_cat_id,
            'uid' => $recode_old['uid'],
            'aid' => $recode_old['aid'],
            'isself' => $recode_old['isself'],
            'name' => $recode_old['name'],
            'type' => $recode_old['type'],
            'year' => $year,
            'month' => $month,
            'day' => $day,
            'hour' => $hour,
            'minute' => $minute,
            'timezone' => $timezone,
            'birth_country' => $recode_old['birth_country'],
            'birth_province' => $recode_old['birth_province'],
            'birth_city' => $recode_old['birth_city'],
            'live_country' => $recode_old['live_country'],
            'live_province' => $recode_old['live_province'],
            'live_city' => $recode_old['live_city'],
            'status' => $recode_old['status'],
            'comments' => $recode_old['comments'],
            'long_deg' => $recode_old['long_deg'],
            'long_min' => $recode_old['long_min'],
            'ew' => $recode_old['ew'],
            'lat_deg' => $recode_old['lat_deg'],
            'lat_min' => $recode_old['lat_min'],
            'ns' => $recode_old['ns'],
            'is_summer' => $is_summer,
            'avatar' => $recode_old['avatar'],
            'from' => $recode_old['from'] ?? 'zhunle',
        ];
        return show(200, 'ok', array_merge($array, $astro_data));
    }


    /**
     * 修改出生地址
     * @return Json
     */
    public function alter_addr()
    {
        $uid = $this->user['id'];
        $country = input('param.birth_country/s');
        $province = input('param.birth_province/s');
        $city = input('param.birth_city/s');
        $longd = input('param.long_deg/d');
        $longm = input('param.long_min/d');
        $ew = input('param.ew/d');
        $latd = input('param.lat_deg/d');
        $latm = input('param.lat_min/d');
        $ns = input('param.ns/d');
        if ($longd < 0 || $longd > 180)
        {
            return show(10723, 'Long_deg Invalid.');
        }
        if ($longm < 0 || $longm > 59)
        {
            return show(10724, 'Long_min Invalid.');
        }
        if ($latd < 0 || $latd > 90)
        {
            return show(10725, 'Lat_deg Invalid.');
        }
        if ($latm < 0 || $latm > 59)
        {
            return show(10726, 'Lat_min Invalid.');
        }
        if ($ew != 1 && $ew != -1)
        {
            return show(10728, 'Ew Invalid.');
        }
        if ($ns != 1 && $ns != -1)
        {
            return show(10729, 'Ns Invalid.');
        }
        $RecodeModel = new Recode();
        $RecodeCatModel = new RecodeCat();

        // 获取档案信息
        try
        {
            $recode_old = $RecodeModel->getRecodeLists($this->user['id'], 1);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '获取档案信息失败');
        }
        //获取档案所属档案袋id
        $recode_cat_id = $RecodeCatModel->getRecodeCatId(['uid' => $uid, 'rid' => $recode_old['id']]);
        $longitude = ($longd + $longm / 60) * $ew;
        $latitude = ($latd + $latm / 60) * $ns;
        // 查询当前星盘日月水金火木土等星落座落宫存入数据库
        $astro_data = getTheRecodeAstro($recode_old['year'], $recode_old['month'], $recode_old['day'], $recode_old['hour'], $recode_old['minute'], $longitude, $latitude, $recode_old['timezone']);
        try
        {
            // 更新档案
            $RecodeModel->UpdateData($this->user['id'], $recode_old['id'], [
                'birth_country' => $country,
                'birth_province' => $province,
                'birth_city' => $city,
                'long_deg' => $longd,
                'long_min' => $longm,
                'ew' => $ew,
                'lat_deg' => $latd,
                'lat_min' => $latm,
                'ns' => $ns,
                'sun' => $astro_data['sun'],
                'moon' => $astro_data['moon'],
                'asc' => $astro_data['asc'],
                'merc' => $astro_data['merc'],
                'venu' => $astro_data['venu'],
                'mars' => $astro_data['mars'],
                'jupi' => $astro_data['jupi'],
                'satu' => $astro_data['satu'],
                'non' => $astro_data['non'],
                'lili' => $astro_data['lili'],
                'juno' => $astro_data['juno'],
                'mc' => $astro_data['mc'],
            ]);
            Db::table('app_recode_astro')->where(['id' => $recode_old['aid']])->update($astro_data);// 更新档案行星数据
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '操作失败', []);
        }

        // 档案更新时更新用户档案缓存
        Cache::rm('recode_' . $recode_old['id']);
        // 档案更新时更新用户档案日月升缓存
        Cache::rm('recode_astro_' . $recode_old['id']);

        //将档案购买的年运订单重新加入队列
//        $this->fortune_redis_job(['rid'=>$recode_old['id'],'uid'=>$recode_old['uid']]);
        $array = [
            'id' => $recode_old['id'],
//            'cid' => $recode_cat_id,
            'uid' => $recode_old['uid'],
            'aid' => $recode_old['aid'],
            'isself' => $recode_old['isself'],
            'name' => $recode_old['name'],
            'type' => $recode_old['type'],
            'year' => $recode_old['year'],
            'month' => $recode_old['month'],
            'day' => $recode_old['day'],
            'hour' => $recode_old['hour'],
            'minute' => $recode_old['minute'],
            'timezone' => $recode_old['timezone'],
            'birth_country' => $country,
            'birth_province' => $province,
            'birth_city' => $city,
            'live_country' => $recode_old['live_country'],
            'live_province' => $recode_old['live_province'],
            'live_city' => $recode_old['live_city'],
            'status' => $recode_old['status'],
            'comments' => $recode_old['comments'],
            'long_deg' => $longd,
            'long_min' => $longm,
            'ew' => $ew,
            'lat_deg' => $latd,
            'lat_min' => $latm,
            'ns' => $ns,
            'is_summer' => $recode_old['is_summer'],
            'avatar' => $recode_old['avatar'],
            'from' => $recode_old['from'] ?? 'zhunle',
        ];
        return show(200, 'ok', array_merge($array, $astro_data));
    }

    /**
     * 修改档案昵称
     * @return Json
     */
    public function alter_name()
    {
        $uid = $this->user['id'];

        $name = htmlspecialchars(input('param.name/s'));
        if ($name == '' || mb_strlen($name, 'utf8') > 10)
        {
            return show(config('code.error'), '昵称无效', []);
        }
        $name = str_replace(array("\r\n", "\r", "\n"), "", $name);

        $validate = validate('Info');
        $a['name'] = $name;
        if ($validate->check($a) !== true)
        {
            return show(config('code.error'), (string)$validate->getError(), []);
        }

        $res = AliyunFilterWord::checkText($name, 'username');
        //若名称违规则退出
        if ($res)
        {
            return show(0, '昵称涉嫌' . $res['label'] . '，请重新设置');
        }

        try
        {
            if ($this->user['rid'])
            {
                (new Recode())->UpdateData($this->user['id'], $this->user['rid'], ['name' => trim($name)]);
            }
            //删除用户缓存
            (new User())->updateUserinfo(['id' => $uid], ['nickname' => trim($name)]);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '操作失败', []);
        }

        if ($this->user['rid'])
        {
            // 档案更新时更新用户档案缓存
            Cache::rm('recode_' . $this->user['rid']);
            // 档案更新时更新用户档案日月升缓存
            Cache::rm('recode_astro_' . $this->user['rid']);
        }
        return show(200, 'ok', []);
    }

    /**
     * 修改档案头像
     * @return Json
     */
    public function alter_avatar()
    {
        $UserModel = new User();
        $avatar = input('param.avatar/s');
        try
        {
            if ($this->user['rid'])
            {
                (new Recode())->UpdateData($this->user['id'], $this->user['rid'], ['avatar' => trim($avatar)]);
            }
            //删除用户缓存
            $UserModel->updateUserinfo(['id' => $this->user['id']], ['avatar' => $avatar]);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '操作失败', []);
        }
        if ($this->user['rid'])
        {
            // 档案更新时更新用户档案缓存
            Cache::rm('recode_' . $this->user['rid']);
            // 档案更新时更新用户档案日月升缓存
            Cache::rm('recode_astro_' . $this->user['rid']);
        }

        return show(200, 'ok', []);
    }

}
